package com.itheima.appserver.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Method;
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.appserver.config.HuanXinConfig;
import com.itheima.appserver.exception.MyException;
import com.itheima.appserver.exception.ResultError;
import com.itheima.appserver.interceptor.UserThreadLocal;
import com.itheima.appserver.service.MyCenterService;
import com.itheima.appserver.service.UserInfoService;
import com.itheima.appserver.service.UserService;
import com.itheima.commons.constants.Constants;
import com.itheima.commons.pojo.*;
import com.itheima.commons.pojo.Question;
import com.itheima.commons.vo.*;
import com.itheima.interfaces.*;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class MyCenterServiceImpl implements MyCenterService {

    @Reference
    private UserInfoApi userInfoAPI;

    @Reference
    private UsersApi usersApi;

    @Reference
    private TanHuaApi tanHuaApi;

    @Autowired
    private RequestService requestService;

    @Autowired
    private HuanXinConfig huanXinConfig;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Reference
    private QuestionApi questionApi;

    @Reference
    private UserApi userApi;

    @Reference
    private SettingsApi settingsApi;

    @Reference
    private BlacklistApi blacklistApi;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private UserService userService;

    @Override
    public UserInfoVo queryUserInfoByUserId(Long userID) {
        UserInfo userInfo = userInfoAPI.findUserInfoByUserId(ObjectUtil.isNotEmpty(userID) ? userID : UserThreadLocal.getUserId());
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setId(userInfo.getId());
        userInfoVo.setAvatar(userInfo.getLogo());
        userInfoVo.setNickname(userInfo.getNickName());
        userInfoVo.setBirthday(userInfo.getBirthday());
        userInfoVo.setAge(userInfo.getAge().toString());
        userInfoVo.setGender(userInfo.getSex() == 1 ? "man" : "woman");
        userInfoVo.setCity(userInfo.getCity());
        userInfoVo.setEducation(userInfo.getEdu());
        userInfoVo.setIncome(userInfo.getIncome());
        userInfoVo.setProfession(userInfo.getIncome());
        userInfoVo.setMarriage(userInfo.getMarriage().equals("未婚") ? 0 : 1);

        return userInfoVo;
    }

    @Override
    public CountsVo counts() {
        //查询喜欢
        Long countLove = usersApi.selectLove(UserThreadLocal.getUserId());
        //查询粉丝
        Long countFans = usersApi.selectFans(UserThreadLocal.getUserId());
        //查询互相喜欢
        //查询自己喜欢人的id
        List<Long> idList = usersApi.selectLoveId(UserThreadLocal.getUserId());

        Long eachLoveCount = usersApi.selectEachLove(idList, UserThreadLocal.getUserId());

        return new CountsVo(eachLoveCount, countLove, countFans);
    }

    /**
     * 1 互相关注 2 我关注 3 粉丝 4 谁看过我
     *
     * @param type
     * @param page
     * @param pagesize
     * @param nickname
     * @return
     */
    @Override
    public PageResult queryLikeList(Integer type, Integer page, Integer pagesize, String nickname) {
        //判断传来的类型 根据不同的类型进行查询
        List<Long> longList = new ArrayList<>();
        switch (type) {
            case 1: {
                //分页查询互相关注
                List<Long> selectLoveId = usersApi.selectLoveId(UserThreadLocal.getUserId());
                longList = usersApi.selectEachLovePage(selectLoveId, UserThreadLocal.getUserId(), page, pagesize);
                break;
            }
            case 2: {
                //分页查询喜欢
                longList = usersApi.selectLovePage(UserThreadLocal.getUserId(), page, pagesize);
                break;
            }
            case 3: {
                //分页查询粉丝
                longList = usersApi.selectFansPage(UserThreadLocal.getUserId(), page, pagesize);
                break;
            }
            case 4: {
                longList = usersApi.visitors(UserThreadLocal.getUserId(), page, pagesize);
                //把当前查询时间放进redis中
                redisTemplate.opsForValue().set(Constants.VISITORS_USER_KEY + UserThreadLocal.getUserId(), Convert.toStr(System.currentTimeMillis()));
                break;
            }
        }
        //查询用户信息
        List<UserLikeListVo> userLikeListVoList = new ArrayList<>();
        Map<Long, UserInfo> userInfoMap = userInfoAPI.findPublishInfo(longList);
        for (UserInfo userInfo : userInfoMap.values()) {
            UserLikeListVo userLikeListVo = new UserLikeListVo();
            userLikeListVo.setId(userInfo.getUserId());
            userLikeListVo.setAvatar(userInfo.getLogo());
            userLikeListVo.setNickname(userInfo.getNickName());
            userLikeListVo.setGender(userInfo.getSex() == 1 ? "man" : "woman");
            userLikeListVo.setAge(userInfo.getAge());
            userLikeListVo.setCity(userInfo.getCity());
            userLikeListVo.setEducation(userInfo.getEdu());
            userLikeListVo.setMarriage(userInfo.getMarriage().equals("未婚") ? 0 : 1);
            //查询匹配度
            RecommendUser recommendUser = tanHuaApi.findScoreByRecommend(userInfo.getUserId(), UserThreadLocal.getUserId());
            userLikeListVo.setMatchRate(Convert.toInt(ObjectUtil.isNotEmpty(recommendUser) ? recommendUser.getScore() : 90));
            UserLike userLike = usersApi.aleadyLove(UserThreadLocal.getUserId(), userInfo.getUserId());
            userLikeListVo.setAlreadyLove(ObjectUtil.isNotEmpty(userLike) ? true : false);
            userLikeListVoList.add(userLikeListVo);
        }
        return new PageResult(page, pagesize, 0L, userLikeListVoList);
    }

    @Override
    public void cancelLove(Long uid) {
        //判断是否是互相喜欢
        UserLike userLike = usersApi.selectIsEachLove(UserThreadLocal.getUserId(), uid);
        if (ObjectUtil.isEmpty(userLike)) {
            //删除环信好友
            requestService.execute(huanXinConfig.getUrl() + huanXinConfig.getOrgName() + "/" + huanXinConfig.getAppName() + "/users/HX_" + UserThreadLocal.getUserId() + "/contacts/users/HX_" + uid, null, Method.DELETE);
        }
        //把用户id 从mongodb中删除
        usersApi.deleteUserId(UserThreadLocal.getUserId(), uid);
        //把用户从redis中删除
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + UserThreadLocal.getUserId(), uid.toString());
    }

    @Override
    public void fansLove(Long uid) {
        //把粉丝id 添加到喜欢表中
        UserLike userLike = new UserLike();
        userLike.setId(new ObjectId());
        userLike.setUserId(UserThreadLocal.getUserId());
        userLike.setLikeUserId(uid);
        userLike.setCreated(System.currentTimeMillis());

        usersApi.saveUserLike(userLike);
        //添加到redis中
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserThreadLocal.getUserId(), uid.toString());
        //添加环信好友
        requestService.execute(huanXinConfig.getUrl() + huanXinConfig.getOrgName() + "/" + huanXinConfig.getAppName() + "/users/HX_" + UserThreadLocal.getUserId() + "/contacts/users/HX_" + uid, null, Method.POST);

    }

    @Override
    public void putUserInfo(String nickname, String birthday) {
        UserInfo userInfo = new UserInfo();
        userInfo.setNickName(nickname);
        userInfo.setBirthday(birthday);
        userInfoAPI.updateByUserInfo(UserThreadLocal.getUserId(), userInfo);
    }

    @Override
    public void updateHeader(MultipartFile headPhoto) {
        userInfoService.updateHead(headPhoto);
    }

    @Override
    public SettingsVo getSettings() {
        SettingsVo settingsVo = new SettingsVo();
        settingsVo.setId(Convert.toInt(UserThreadLocal.getUserId()));
        // 查询陌生人问题
        Question question = questionApi.strangerQuestions(UserThreadLocal.getUserId());
        settingsVo.setStrangerQuestion(ObjectUtil.isNotEmpty(question) ? question.getTxt() : "你喜欢什么颜色");
        //查询手机号
        User user = userApi.selectPhoneById(UserThreadLocal.getUserId());
        settingsVo.setPhone(user.getMobile());
        //查询设置表 根据id 查询记录
        Settings settings = settingsApi.selectById(UserThreadLocal.getUserId());
        settingsVo.setLikeNotification(settings.getLikeNotification() == 1 ? true : false);
        settingsVo.setPinglunNotification(settings.getPinglunNotification() == 1 ? true : false);
        settingsVo.setGonggaoNotification(settings.getGonggaoNotification() == 1 ? true : false);
        return settingsVo;
    }

    @Override
    public void settingQuestion(String content) {
        //判断是否已有问题
        Question que = questionApi.strangerQuestions(UserThreadLocal.getUserId());
        //没有问题 新增
        if (ObjectUtil.isEmpty(que)) {
            Question question = new Question();
            question.setUserId(UserThreadLocal.getUserId());
            question.setTxt(content);
            question.setCreated(new Date());
            question.setUpdated(new Date());
            questionApi.saveQuestion(question);
        } else {
            //修改问题
            questionApi.updateQuestion(UserThreadLocal.getUserId(), content);
        }

    }

    @Override
    public PageResult blacklist(Integer page, Integer pagesize) {
        //查询黑名单
        List<BlackList> blackLists = blacklistApi.selectBlackList(UserThreadLocal.getUserId(), page, pagesize);
        //根据black_user_id 查询用户信息
        List<Long> blackUserId = CollUtil.getFieldValues(blackLists, "blackUserId", Long.class);
        Map<Long, UserInfo> publishInfo = userInfoAPI.findPublishInfo(blackUserId);
        List<BlacklistVo> blacklistVoList = new ArrayList<>();

        for (BlackList blackList : blackLists) {
            UserInfo userInfo = publishInfo.get(blackList.getBlackUserId());
            BlacklistVo blacklistVo = new BlacklistVo();
            blacklistVo.setId(Convert.toInt(userInfo.getUserId()));
            blacklistVo.setAvatar(userInfo.getLogo());
            blacklistVo.setNickname(userInfo.getNickName());
            blacklistVo.setGender(userInfo.getSex() == 1 ? "man" : "woman");
            blacklistVo.setAge(userInfo.getAge());
            blacklistVoList.add(blacklistVo);
        }
        return new PageResult(page, pagesize, 0L, blacklistVoList);
    }

    @Override
    public void removeBlackList(Long uid) {
        blacklistApi.deleteBlackList(UserThreadLocal.getUserId(), uid);
    }

    @Override
    public void notifications(Boolean likeNotification, Boolean pinglunNotification, Boolean gonggaoNotification) {

        settingsApi.updateNotifications(UserThreadLocal.getUserId(), Convert.toLong(likeNotification ? 1 : 0), Convert.toLong(pinglunNotification ? 1 : 0), Convert.toLong(gonggaoNotification ? 1 : 0));
    }

    @Override
    public void sendVerificationCode() {
       userService.userSendLoginMsg(UserThreadLocal.getUserPhone());
    }

    @Override
    public Boolean checkVerificationCode(String verificationCode) {
        // 从redis中获得验证码
        String s = redisTemplate.opsForValue().get(Constants.SMS_CODE + UserThreadLocal.getUserPhone());
        if (StrUtil.equals(s, verificationCode)) {
            redisTemplate.delete(Constants.SMS_CODE + UserThreadLocal.getUserId());
            return true;
        }
        return false;
    }

    @Override
    public void savePhone(String phone) {
        if (!Validator.isMobile(phone)) {
            throw new MyException(ResultError.phoneError());
        }
        //查询手机号是否存在
        User user = userApi.selectUserByPhone(phone);
        if (ObjectUtil.isNotEmpty(user)) {
            throw new MyException(ResultError.phoneIsError());
        }
        userApi.savePhone(UserThreadLocal.getUserId(), phone);
    }
}
